iT邦幫忙

2025 iThome 鐵人賽

DAY 18
1
AI & Data

讓電腦聽懂人話:30 天 NLP 入門系列 第 18

Day 18|最大間隔的線性分類:SVM

  • 分享至 

  • xImage
  •  

引言

在前一篇文章,我們介紹了 Logistic Regression 🚪傳送門,它的做法是用 Sigmoid function 把資料轉成機率,再依機率來進行分類。
這個方法比較直觀也容易理解,它只要能把不同類別大致分開就可以了。就好比你想把兩群人分開,只要隨便畫條線「剛好分開」就行了。
但是在資料很複雜、分布不規則時,這條隨便畫的線可能會離資料點太近,分類結果就容易出錯。

於是,今天我們要介紹另一個更嚴謹的畫線高手 — Support Vector Machine(SVM)。SVM 的目標不只是把不同類別分開,它還會去拉開類別之間的距離。可以想像成在分兩群人時,它會刻意拉出一個 安全距離,讓兩群人之間有一個緩衝空間,確保分類不會混在一起。

那 SVM 到底是怎麼做到的呢?我們就一起來看一下它的計算原理,最後再動手做一點實作練習吧~~

Support Vector Machine (SVM) 支持向量機

SVM 主要有四個核心概念:

1. 最大間隔(Max Margin)

要用一條線(Decision Boundry)把資料分成兩類,可以有很多種分法。但 SVM 追求的不只是把資料分開,而是選擇一條 「讓兩類之間距離最大」 的邊界。所以 SVM 目標是讓不同類別的資料之間拉出 最大間隔(Max Margin)

圖片來源:https://www.inovex.de/de/blog/support-vector-machines-guide/

2. 支持向量(Support Vectors)

決定最大間隔的並不是所有資料點,而是只有離邊界最近的那些點會影響 SVM 的決策線。這些關鍵的資料點就稱為 支持向量(Support Vectors)

3. 懲罰參數(C)

雖然 SVM 盡力畫出有最大間隔的決策線,但它還是允許一定程度的錯誤。它會透過 懲罰參數 𝐶 來控制容忍程度。

  • 𝐶 大:追求嚴格分開 → 模型可能過擬合
  • 𝐶 小:容忍一些錯誤 → 換取更寬的安全間隔

透過調整 𝐶 值,就是在 「準確度」「泛化能力」 之間找平衡~

4. 核技巧(Kernel Trick)

有時資料會非常複雜,呈現 「線性不可分」 的狀態,也就是說用一條直線沒辦法切開,如下圖。

圖片來源:https://www.naukri.com/code360/library/linear-vs-non-linear-classification

SVM 有個神奇的功能可以解這題,叫做 核技巧(Kernel Trick)。這個做法是把資料投影到更高維的空間。讓原本聚成一團的資料,在新空間中可以被一條線分開。

圖片來源:https://medium.com/@Suraj_Yadav/what-is-kernel-trick-in-svm-interview-questions-related-to-kernel-trick-97674401c48d

以下是三種常見的核函數:

  1. 線性核(Linear Kernel):最簡單的核函數,就是直接在原始特徵空間中找一條超平面分開資料。

  2. 多項式核(Polynomial Kernel):把原始資料映射到高維的多項式空間,讓原本線性不可分的資料,可以在高維空間用超平面分開。

  3. RBF 核/高斯核(Radial Basis Function/Gaussian Kernel):RBF 核會把每個資料點轉換成一個「高維的能量場」。

    • 離中心越近 → 影響力越大
    • 離中心越遠 → 影響力越小

    最終在這個高維空間中找一個平面,把不同類別的「能量雲」分開。

程式實作

1. 前置預備(詳細步驟分解可以參考這篇 Naive Bayes

  • 讀取資料:kaggle 的 IMDb 50K Cleaned Movie Reviews
  • 資料劃分:訓練集跟測試集切分為 8:2
  • 特徵轉換:文字轉為 TF-IDF 向量
import kagglehub
import pandas as pd
import os
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer

# 讀取資料
path = kagglehub.dataset_download("ibrahimqasimi/imdb-50k-cleaned-movie-reviews")
csv_path = os.path.join(path, "IMDB_cleaned.csv")  
df = pd.read_csv(csv_path)

# 資料劃分
X = df["cleaned_review"]
y = df["sentiment"]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 特徵轉換
vectorizer = TfidfVectorizer(stop_words="english", max_features=5000)
X_train_vec = vectorizer.fit_transform(X_train)
X_test_vec = vectorizer.transform(X_test)

https://ithelp.ithome.com.tw/upload/images/20250930/201787197e0c5O8UGa.png

2. SVM 模型訓練與評估

kernel 可選:linear, rbf, poly, sigmoid

from sklearn.svm import SVC

# 建立模型
svm_model = SVC(kernel="rbf", random_state=42) 
svm_model.fit(X_train_vec, y_train)
y_pred = svm_model.predict(X_test_vec)

# 評估
print("=== SVM ===")
print("Accuracy:", f"{accuracy_score(y_test, y_pred):.3f}")
print("Precision:", f"{precision_score(y_test, y_pred, pos_label='positive'):.3f}")
print("Recall:", f"{recall_score(y_test, y_pred, pos_label='positive'):.3f}")
print("F1 Score:", f"{f1_score(y_test, y_pred, pos_label='positive'):.3f}")
print("\n分類報告:\n", classification_report(y_test, y_pred))

# 混淆矩陣
cm = confusion_matrix(y_test, y_pred, labels=["positive", "negative"])
plt.figure(figsize=(5,4))
sns.heatmap(cm, annot=True, fmt="d", cmap="Oranges",
            xticklabels=["positive", "negative"],
            yticklabels=["positive", "negative"])
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.title("Confusion Matrix - SVM")
plt.show()
=== SVM ===
Accuracy: 0.859
Precision: 0.828
Recall: 0.883
F1 Score: 0.855

分類報告:
               precision    recall  f1-score   support

    negative       0.89      0.84      0.86       530
    positive       0.83      0.88      0.85       470

    accuracy                           0.86      1000
   macro avg       0.86      0.86      0.86      1000
weighted avg       0.86      0.86      0.86      1000

https://ithelp.ithome.com.tw/upload/images/20250930/20178719apWV0RqiC5.png

結語

今天的 SVM 介紹到這裡,也代表我們的傳統機器學習方法告一段落啦~~
這幾天我們提到了機率統計模型樹模型,以及線性分類模型。但是隨著資料越來越龐大也越來越複雜,單靠這些方法在計算量和模型的彈性上就會逐漸受限。

這時候我們就需要更強大的工具,能自動學習特徵、處理非線性,甚至更高維度的資料。於是,「深度學習」(Deep Learning) 就登場啦!!

明天我們會從 神經網路(Neural Networks) 開始,來看看它是如何模仿人腦的思考方式,接著一步步帶大家走進深度學習的世界~~~

References


上一篇
Day 17|機率式的線性分類:Logistic Regression
下一篇
Day 19|模擬大腦的世界(上):Neural Network 入門
系列文
讓電腦聽懂人話:30 天 NLP 入門22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言